
#ifndef __physics_vehicleH__
#define __physics_vehicleH__

#include "physics.h"

// Only implemented for Bullet
#ifndef __PHYSICS_BULLET__
#error Not implemented
#endif

namespace WtfEngine {
	class Vehicle: public Physical {
	public:
		typedef struct VehicleCreationOptions: public Physical::tCreationOptions {
			/// This should increase with the mass of the vehicle in order to give
			/// a good simulation.
			tScalar		SuspensionStiffness;
			tScalar		SuspensionDamping;
			tScalar		SuspensionCompression;
			
			VehicleCreationOptions(const Physical::tCreationOptions opts = Physical::tCreationOptions(), tScalar stiffness = 20.0, tScalar damping = 5,
				tScalar compression = 4):
			Physical::tCreationOptions(opts), SuspensionStiffness(stiffness), SuspensionDamping(damping),
				SuspensionCompression(compression) {};
		} tCreationOptions;

	protected:
		struct WheelInfo {
			Orientation3D					Orientation;
			WtfGraphics::GraphicsData::tRef rWheelGraphics;

			WheelInfo(const Orientation3D& ori, const WtfGraphics::GraphicsData::tRef& rWheelGfx):
				Orientation(ori), rWheelGraphics(rWheelGfx) {
			};
		};

		btRaycastVehicle *					mpRaycastVehicle;
		btRaycastVehicle::btVehicleTuning	mTuning;

	public:
		Vehicle(const tCreationOptions& opts, const WtfGraphics::GraphicsData::tCacheRef& rChassisGraphics,
			const PhysicalModel::tCacheRef& rChassisModel);

		void AddWheel(const tPosition& vPos, const WtfGraphics::GraphicsData::tRef& rWheelGfx, const Orientation3D& wheelOri,
			const tDirection& vAxle, const tDirection& vMountPoint, tScalar radius, bool isFrontWheel = false);

		/// Render is overridden to allow drawing of wheels.
		void Render();


		// These functions allow control of any basic type of vehicle.

		/// This sets the throttle value, which should be a value in the range [-1, 1].
		/// The rest of the functions below follow the same principle.
		virtual void setThrottle(tScalar amt) = 0;
		virtual void setBrake(tScalar amt) = 0;
		virtual void setHandBrake(tScalar amt) = 0;
		virtual void setSteering(tScalar amt) = 0;
	};
};

#endif
